package main;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

/**
 * @author Maria Adriana 
 */

@SuppressWarnings("unchecked")

public class SyntAttributes implements Cloneable
{
	private ArrayList<String> contextList;
	private ArrayList targetList;
	private ArrayList<String> keyList;
	
	//new attributes for xdf validation
	private ArrayList<Boolean> c;//list true/false
	private String dc;//one data element
	private ArrayList<String> ds;//one OR MORE data element
	private ArrayList<Inters> inters;//list of tuples <l1, l2> l1 for DS and l2 for DC
	private String nodeName;
	
	private ArrayList<String> dr;//one OR MORE data element
	
	
	public SyntAttributes()
	{
		contextList = new ArrayList<String>();
		targetList = new ArrayList();
		keyList = new ArrayList<String>();
		
		//new attributes for xdf validation
		//nodeName = new String();
		c = new ArrayList<Boolean>();
		dc = new String();
		ds = new ArrayList<String>();
		inters = new ArrayList();
	}
	
	public void setDsSize(int size)
	{
		ds = new ArrayList<String>(size);
		for(int i=0;i<size;i++)
			ds.add(i, "");
	}
	
	public void addC(boolean element)
	{
		c.add(element);
	}
	
	public void addInters (Inters element)
	{
		inters.add(element);
	}

		
	public void concatInters (ArrayList<Inters> element)
	{
		for (Iterator<Inters> i = element.iterator(); i.hasNext();) 
		{
			Inters c = (Inters) i.next();
			inters.add(c);
		}
	}

	public void setDc(String element)
	{
		dc = element;
	}
	
	public void setDc(StringBuffer element)
	{
		dc.valueOf(element.toString());
	}
	
	public void setDs(ArrayList<String> a)
	{
		ds = a;
	}
	
	public void setC(ArrayList<Boolean> a)
	{
		c = a;
	}
	
	public void setDs(String element, int position)
	{
		ds.set(position, element);
	}

	public void setDs(StringBuffer element, int position)
	{
		ds.set(position, element.toString()); //coloquei to string pois DS eh um array de string, serah mesmo?
	}
		
	public void setInters(ArrayList<Inters> element)
	{
		inters = element;
	}
		
	public SyntAttributes join (SyntAttributes aux, Hashtable<String,ArrayList<Inters>> htIntersXfd, 
			                    String dataPos)
	{	
		ArrayList<Inters> newInters;
		Inters inters1;
		Inters inters2;
		Inters inters1N, inters2N;
	
	
		if (this.getInters().isEmpty())
		{
			newInters = aux.getInters();
		}
		else
		{
		   if (aux.getInters().isEmpty())
		   {
			   newInters = this.getInters();
		   }	   
		   else
		   {
				 newInters = new ArrayList<Inters>();
				 
				 // puts in newInters all intersections that are complete/calculated from syntattant  
				 for (Iterator<Inters> it1 = this.getInters().iterator(); it1.hasNext();)
				 {
					   inters1 = (Inters) it1.next();
					   if (!inters1.getDs().contains("#") && !inters1.getDc().equals("#"))
						   newInters.add(inters1);
					   else
					   {
						   inters1N = new Inters(inters1);
						   for (Iterator<Inters> it2 = aux.getInters().iterator(); it2.hasNext();)
						   {
				  	              inters2 = (Inters) it2.next();
				  	            //  System.out.println("Inters2 --> "+inters2.toString());   	
				  	    	   
							      for(int i=0;i<inters2.getDs().size();i++)
							      {
									    if (inters1.getDs().get(i).equals("#"))
									    {
				                               inters1N.setDs((String)inters2.getDs().get(i),i);    					
									    }
								  }
							      if (inters1.getDc().equals("#"))
							      {
				                        inters1N.setDc(inters2.getDc());    					
							      }
							   
							      if (!containsEq(newInters,inters1N))
						    	       newInters.add(inters1N);
						   } //end for	
					   } //end else if
				 } // end for	   
						   				   
				 // puts in newInters all intersections that are complete/calculated from syntatt  
				 for (Iterator<Inters> it2 = aux.getInters().iterator(); it2.hasNext();)
				 {
					   inters2 = (Inters) it2.next();
					   if (!inters2.getDs().contains("#") && !inters2.getDc().equals("#"))
						   newInters.add(inters2);
					   else
					   { 	   
						   inters2N = new Inters(inters2);
		                   for (Iterator<Inters> it1 = this.getInters().iterator(); it1.hasNext();)
		                   {
			  		              inters1 = (Inters) it1.next();
			  		       
			  			          for(int i=0;i<inters2.getDs().size();i++)
			  			          {
				  					    if (inters2.getDs().get(i).equals("#"))
				  					    {
				                                 inters2N.setDs((String)inters1.getDs().get(i),i);    					
				  					    }
			  			          }
				  			      
			  			          if (inters2.getDc().equals("#"))
				  			      {
			  			        	  inters2N.setDc(inters1.getDc());    					
				  			      }
			  			   
			  			          if (!containsEq(newInters,inters2N))
			  			        	  newInters.add(inters2N);
		                   } //end for	
		  	         	} //end if
		           } // end for	         	         	        	       
	  	   	} //end else
		} //end else   	    	   
	   
	    if (!newInters.isEmpty())
	    {
	       htIntersXfd.put(dataPos,newInters);
	    }   
	    
	    //System.out.println("Em join: htIntersXdf"+htIntersXfd.toString());
	    //System.out.println("new inters: "+newInters.toString());
	    
	    aux.inters = new ArrayList<Inters>();
		this.setInters(newInters);
		
		return this;
	}
	
	public Boolean containsEq (ArrayList<Inters> newInters, Inters it)
	{
		Inters aux = new Inters();
		for (Iterator<Inters> it1 = newInters.iterator(); it1.hasNext();)
		{
	     	  aux = (Inters) it1.next();
	          if (aux.getDs().equals(it.getDs()) && aux.getDc().equals(it.getDc()) )// e agora senho?? o q faz esse if
	     	 
	        		  return true;
		}    		  
	          
		return false;
	}
	

	
	public void setContextList(ArrayList<String> c)
	{
		contextList = c;
	}

	public ArrayList<String> getContextList()
	{
		return contextList;
	}

	public void addContextList(String s)
	{
		contextList.add(s);
	}

	public boolean containsContextList(String s)
	{
		if (contextList.contains(s))
			return true;
		
		return false;
	}

	public void clearContextList()
	{
		contextList.clear();
	}

	public int sizeContextList()
	{
		return contextList.size();
	}

	public void setTargetList(ArrayList t)
	{
		targetList = t;
	}

	public ArrayList getTargetList()
	{
		return targetList;
	}

	public void addTargetList(ArrayList al)
	{
		targetList.add(al);
	}

	public int sizeTargetList()
	{
		return targetList.size();
	}

	public boolean containsTargetList(String s)
	{
		if (targetList.contains(s))
			return true;
		
		return false;
	}

	public void setKeyList(ArrayList<String> k)
	{
		keyList = k;
	}

	public ArrayList<String> getKeyList()
	{
		return keyList;
	}


	public void addKeyList(String s)
	{
		keyList.add(s);
	}

	public boolean containsKeyList(String s)
	{
		if (keyList.contains(s))
			return true;
		
		return false;
	}

	public int sizeKeyList()
	{
		return keyList.size();
	}

	public boolean isEmpty()
	{
		if (c.isEmpty() && ds.isEmpty() && inters.isEmpty() && dc.isEmpty())
			return true;
		else
			return false;
	}

	public void addAll(SyntAttributes st)
	{
		contextList.addAll(st.contextList);
		targetList.addAll(st.targetList);
		keyList.addAll(st.keyList);
	}

	public void addAllKey(SyntAttributes st)
	{
		keyList.addAll(st.keyList);
	}

	public void addAllTarget(SyntAttributes st)
	{
		targetList.addAll(st.targetList);
	}

	public void addAllContext(SyntAttributes st)
	{
		contextList.addAll(st.contextList);
	}
	
	public void setNodeName(String node)
	{
		nodeName = node;
	}
	
	public String getNodeName()
	{
		return nodeName;
	}
	
	public String getDc()
	{
		return dc;
	}
	
	public ArrayList<String> getDs()
	{
		return ds;
	}
	
	public ArrayList<Inters> getInters()
	{
		return inters;
	}
	
	public ArrayList<Boolean> getC()
	{
		return c;
	}	

	public String toString()
	{
		StringBuffer strbuff = new StringBuffer();
		if(!ds.isEmpty())
			strbuff.append("ds = " + toStringAux(ds)+", ");
		if(!dc.isEmpty())
			strbuff.append("dc = <" + dc + ">, ");
		if(!inters.isEmpty())
			strbuff.append("inters = {" + toStringAux2(inters) + "}, ");
		if(!c.isEmpty())
			strbuff.append("c = " + toStringAux(c));
		
		String str = strbuff.toString();
		
		return str;
	}
	
	public String toStringAux(ArrayList list)
	{
		StringBuffer strbuff = new StringBuffer("<");
		
		for(int i=0;i<list.size();i++)
			strbuff.append(list.get(i).toString()).append(", ");
		
		strbuff.append(">");
		
		return strbuff.toString();
	}
	
	public String toStringAux2(ArrayList<Inters> list)
	{
		StringBuffer strbuff = new StringBuffer();
		Inters aux;
		
		for(int i=0;i<list.size();i++)
		{
			aux = (Inters) list.get(i);
			strbuff.append("<");
			//for(int j=0; j<aux.size();j++)
			strbuff.append(aux.getDs().toString()).append(", ");
			strbuff.append(aux.getDc().toString());
			strbuff.append(">, ");
		}
		
		return strbuff.toString();
	}
}
